<?php
/**
 *+------------------
 * Ingenious
 *+------------------
 * Copyright (c) https://gitee.com/ingenstream/ingenious  All rights reserved.
 *+------------------
 * Author: Mr. April (405784684@qq.com)
 *+------------------
 * Software Registration Number: 2024SR0694589
 * Official Website: http://www.ingenstream.cn
 */

namespace madong\laravel\wf\model;

use Carbon\Carbon;
use madong\ingenious\interface\model\IProcessTaskHistory;
use Illuminate\Database\Eloquent\Relations\HasMany;
use madong\laravel\wf\basic\BaseModel;

class ProcessTaskHistory extends BaseModel implements IProcessTaskHistory
{

    /**
     * 数据表主键
     *
     * @var string
     */
    protected $primaryKey = 'id';

    /**
     * 表名
     *
     * @var string
     */
    protected $table = 'wf_process_task_history';

    /**
     * 是否自增id
     *
     * @var bool
     */
    public $incrementing = false;

    /**
     * 是否指定时间戳
     *
     * @var bool
     */
    public $timestamps = true;

    // 自定义时间戳字段
    const CREATED_AT = 'create_time'; // 自定义创建时间字段
    const UPDATED_AT = 'update_time'; // 自定义更新时间字段

    protected $appends = ['create_date', 'update_date', 'expire_date', 'finish_date'];

    protected $casts = [
        'variable' => 'array', // 将 JSON 字段转换为 PHP 数组
    ];

    protected $fillable = [
        'id',
        'process_instance_id',
        'task_name',
        'display_name',
        'task_type',
        'perform_type',
        'task_state',
        'operator',
        'finish_time',
        'expire_time',
        'form_key',
        'task_parent_id',
        'variable',
        'create_time',
        'create_by',
        'update_time',
        'update_by',
    ];

    /**
     * 追加更新时间
     *
     * @return string|null
     */
    public function getExpireDateAttribute(): ?string
    {
        if ($this->getAttribute('expire_time')) {
            try {
                $timestamp = $this->getRawOriginal('expire_time');
                if (empty($timestamp)) {
                    return null;
                }
                $carbonInstance = Carbon::createFromTimestamp($timestamp);
                return $carbonInstance->setTimezone(config('app.default_timezone'))->format('Y-m-d H:i:s');
            } catch (\Exception $e) {
                return null;
            }
        }
        return null;
    }

    /**
     * 完成时间
     *
     * @return string|null
     */
    public function getFinishDateAttribute(): ?string
    {
        if ($this->getAttribute('finish_time')) {
            try {
                $timestamp = $this->getRawOriginal('finish_time');
                if (empty($timestamp)) {
                    return null;
                }
                $carbonInstance = Carbon::createFromTimestamp($timestamp);
                return $carbonInstance->setTimezone(config('app.default_timezone'))->format('Y-m-d H:i:s');
            } catch (\Exception $e) {
                return null;
            }
        }
        return null;
    }

    /**
     * ID-搜索器
     *
     * @param $query
     * @param $value
     */
    public function scopeId($query, $value)
    {
        if (!empty($value)) {
            $query->where('id', $value);
        }
    }

    /**
     * 流程实例ID-搜索器
     *
     * @param $query
     * @param $value
     */
    public function scopeProcessInstanceId($query, $value)
    {
        if (!empty($value)) {
            $query->where('process_instance_id', $value);
        }
    }

    /**
     * 任务名称自动识别in搜索器
     *
     * @param $query
     * @param $value
     */
    public function scopeTaskName($query, $value)
    {
        if (!empty($value)) {
            if (is_array($value)) {
                $query->whereIn('task_name', implode(',', $value));
            } else {
                $isTrue = count(explode(',', $value)) > 1;
                if ($isTrue) {
                    $query->whereIn('task_name', $value);
                } else {
                    $query->where('task_name', $value);
                }
            }
        }
    }

    public function scopeDisplayName($query, $value)
    {
        if (!empty($value)) {
            $query->where('display_name', $value);
        }
    }

    /**
     * 任务类型-搜索器
     *
     * @param $query
     * @param $value
     */
    public function scopeTaskType($query, $value)
    {
        if (!empty($value)) {
            $query->where('task_type', $value);
        }
    }

    /**
     * 参与类型-搜索器
     *
     * @param $query
     * @param $value
     */
    public function scopePerformType($query, $value)
    {
        if (!empty($value)) {
            $query->where('perform_type', $value);
        }
    }

    /**
     * 任务状态-搜索器
     *
     * @param $query
     * @param $value
     */
    public function scopeTaskState($query, $value)
    {
        if (!empty($value)) {
            $query->where('task_state', $value);
        }
    }

    /**
     * 任务状态自动识别notIn 搜索器
     *
     * @param $query
     * @param $value
     */
    public function scopeNotInTaskState($query, $value)
    {
        if (!empty($value)) {
            if (is_array($value)) {
                $query->whereNotIn('task_state', implode(',', $value));
            } else {
                $isTrue = count(explode(',', $value)) > 1;
                if ($isTrue) {
                    $query->whereNotIn('task_state', explode(',', $value));
                } else {
                    $query->where('task_state', '<>', $value);
                }
            }
        }
    }

    /**
     * 任务处理人
     *
     * @param $query
     * @param $value
     */
    public function scopeOperator($query, $value)
    {
        if (!empty($value)) {
            $query->where('operator', $value);
        }
    }

    /**
     * 父任务ID-搜索器
     *
     * @param $query
     * @param $value
     */
    public function scopeTaskParentId($query, $value)
    {
        if (!empty($value)) {
            $query->where('task_parent_id', $value);
        }
    }

    public function actors(): HasMany
    {
        return $this->hasMany(ProcessTaskActorHistory::class, 'process_task_id', 'id');
    }

    /**
     * 关联父级流程实例
     *
     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
     */
    public function instance(): \Illuminate\Database\Eloquent\Relations\BelongsTo
    {
        return $this->belongsTo(ProcessInstanceHistory::class, 'process_instance_id');
    }

}
